package top.eggcode.security.session;

import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import top.eggcode.common.exception.ApplicationException;
import top.eggcode.system.client.UserClientService;
import top.eggcode.system.client.model.Account;

/**
 * Title: 会话身份
 * Description: TODO
 * Date: 2021/6/11 14:23
 *
 * @author JiaQi Ding
 * @version 1.0
 */
//@Component
@RequiredArgsConstructor
public class AppSessionRealm extends AuthorizingRealm {

    private final UserClientService userClientService;

    /**
     * 重写令牌类型的验证
     *
     * @param token 令牌
     * @return 结果
     */
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof UsernamePasswordToken;
    }

    /**
     * 获取用户权限
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        String username = (String) principalCollection.getPrimaryPrincipal();
        Account account = userClientService.findAccount(username).getData();
        if (account != null) {
            throw new ApplicationException("找不到账户信息");
        }

        SimpleAuthorizationInfo authorization = new SimpleAuthorizationInfo();
        // 绑定角色码
        authorization.addRoles(userClientService.getRoleCodeList(account.getUsername()).getData());
        // 绑定操作码
        authorization.addStringPermissions(
                userClientService.getPowerCodeList(account.getUsername()).getData()
        );
        return authorization;
    }

    /**
     * 获取用户身份
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {

        // 委托人
        String username = (String) authenticationToken.getPrincipal();

        // 凭证
        String token = String.valueOf((char[]) authenticationToken.getCredentials());

        // 没有登录标记
        if (StringUtils.isBlank(username)) {
            throw new IncorrectCredentialsException("无效 token");
        }

        return new SimpleAuthenticationInfo(
                username,
                token,
                getName());
    }
}
